﻿using System;
using System.Linq;
using System.Data.Entity;
using System.Linq.Expressions;
using System.Collections.Generic;

namespace Common
{
    public abstract class RepositoryBase<tEntity, tType> : IRepository<tEntity, tType>
        where tEntity : MasterEntityBase<tType>
        where tType : struct
    {
        #region Declarations
        protected DbContext Context { get; set; }
        protected IDbSet<tEntity> DbSet { get; set; }
        #endregion

        #region ctor
        public RepositoryBase(IDbContext _context)
        {
            Context = _context as DbContext;
            if (Context == null) throw new Exception("Context is not a valid DB Context");
            DbSet = Context.Set<tEntity>();
        }
        #endregion

        #region Get
        public virtual tEntity GetById(tType Id)
        {
            return DbSet.Find(Id);
        }

        public virtual IEnumerable<tEntity> GetAll()
        {
            return DbSet;
        }

        public virtual IEnumerable<tEntity> GetByConditoin(Expression<Func<tEntity, bool>> Predicate)
        {
            return DbSet.Where(Predicate);
        }
        #endregion

        #region Save
        public virtual tType AddUpdate(tEntity entity)
        {
            tEntity oldEntity = GetById(entity.ID);
            if (oldEntity != null)
            {
                Context.Entry<tEntity>(oldEntity).CurrentValues.SetValues(entity);
                Context.Entry<tEntity>(entity).State = EntityState.Modified;
            }
            else
            {
                DbSet.Add(entity);
                Context.Entry<tEntity>(entity).State = EntityState.Added;
            }
            SaveChanges();
            return entity.ID;
        }
        #endregion

        #region Delete
        public virtual void Delete(tType Id)
        {
            var entity = GetById(Id);
            if (entity == null) return;
            DbSet.Remove(entity);
            SaveChanges();
        }
        #endregion

        #region Commit
        protected virtual void SaveChanges()
        {
            if (Context.ChangeTracker.HasChanges())
                Context.SaveChanges();
        }
        #endregion

    }
}
